package breeze.framework.reflect;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

import sun.reflect.Reflection;

/**
 * @author breeze
 * @email breeze_java@163.com
 * @date 2015年11月14日 00:22:35
 * @description 
 */
@SuppressWarnings({ "rawtypes", "restriction" })
public class Reflector extends ClassLoader{
	
	/**
	 * 从指定目录加载某个类
	 * 应用场景 : 
	 * 最初是为了修改javafx.embed.swing.SwingNode的源码而写.
	 * 因为SwingNode是有ExtClassLoader加载的,所以直接在src的相同路径中建立一个SwingNode也无法覆盖
	 * 此类,这种方法只能覆盖由AppClassLoader加载的类.后因SwingNode包中非public类实在是太多,全部加载太费事,故放弃这种实现
	 * @param classpath
	 * @param fullName
	 * 
	 		Class<?> clazz = Reflector.defineClassByCatalog("E:\\Repository\\breeze\\breeze-override\\target\\classes\\", "javafx.embed.swing.SwingNode");
			Object swingnode = clazz.newInstance();
			Reflector.executeMethod(swingnode, "print");
			Reflector.executeMethod(swingnode, "setBounds",
					new Object[] {600,200,200,200},
					new Class[]{double.class,double.class,double.class,double.class});
			SwingUtilities.invokeLater(new Runnable() {
		         @Override
		         public void run() {
		        	 Reflector.executeMethod(swingnode, "setContent",
		        			 new Object[]{browser.getPanel()},
		        			 new Class[]{JComponent.class});
		         }
			});
	 * 
	 * 
	 */
	private static Reflector loader = new Reflector();
	/*public static Class<?> defineClassByCatalog(String classpath,String fullName) {
		
		try {
			if(!classpath.endsWith("/") && !classpath.endsWith("\\")) {
				classpath = classpath + "/";
			}
			File file = new File(classpath + fullName.replace(".", "/") + ".class");
			if(!file.exists() || file.isDirectory()) {
				return null;
			}
			
			byte[] bytes = new byte[(int) file.length()];
			FileInputStream stream = new FileInputStream(file);
			stream.read(bytes);
			stream.close();
			Class<?> clazz = loader.defineClass(fullName, bytes, 0, bytes.length);
			System.out.println(fullName);
			File directory = file.getParentFile();
			File[] files = directory.listFiles();
			for (int i = 0; i < files.length; i++) {
				if(files[i].getName().startsWith(clazz.getSimpleName() + "$")) {
					FileInputStream _stream = new FileInputStream(files[i]);
					byte[] _bytes = new byte[(int) files[i].length()];
					_stream.read(_bytes);
					_stream.close();
					String name = fullName.substring(0, fullName.lastIndexOf(".") + 1) + files[i].getName().substring(0, files[i].getName().lastIndexOf("."));
					System.out.println(name);
					loader.defineClass(name, _bytes, 0, _bytes.length);
				}
			}
			
			System.err.println("class : " + clazz + " is defined");
			return clazz;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}*/
	
	/**
	 * 静态调用时每次传入Class时需要写死,不方便,所以主动获取
	 * level=0 Reflection层
	 * level=1  当前方法所在的类
	 * level=2  当前方法的调用者
	 * level=3 当前方法的调用者的调用者
	 * 以此类推
	 */
	@SuppressWarnings({"deprecation"})
	public static Class<?> findInvoker(int level){
		Class<?> clazz = null;
		try {
			clazz = Reflection.getCallerClass(level);
		} catch (Exception e) {
			try {
				StackTraceElement[] stackElements = new Throwable().getStackTrace();
				String msg = ".";
				if(stackElements.length == level){
					msg = stackElements[level-1].toString();
				}else if(stackElements.length > level){
					msg = stackElements[level].toString();
				}
				String cls = msg.substring(0,msg.indexOf("("));
				cls = cls.substring(0,cls.lastIndexOf("."));
				clazz = Class.forName(cls);
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
		return clazz;
	}
	
	/**
	 * 首先尝试调用对象的setter方法,因为setter方法中可能存在处理逻辑.
	 * 无法调用setter的情况下再尝试直接给属性赋值
	 */
	public static boolean setProperty(Object obj,String name,Class<?> type,Object value) {
		Class<?> clazz = obj.getClass();
		Method setter = null;
		try {
			//1.获取正常的setter,setName
			setter = clazz.getMethod("set" + name.substring(0, 1).toUpperCase() + name.substring(1),type);
		} catch (NoSuchMethodException e) {
			try {
				//2.如变量aName的setter就是setaName();
				setter = clazz.getMethod("set" + name,type);
			} catch (NoSuchMethodException e1) {
				return setProperty(obj,name,value);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			if(null != setter) {
				Class<?>[] clasees = setter.getParameterTypes();
				if(clasees.length != 1) {
					System.err.println("can't find the method which has one parameter");
					return false;
				}
				if(null == value) {
					setter.invoke(obj,new Object[]{null});
					return true;
				}else {
					setter.invoke(obj,cast(clasees[0], value));
					return true;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.err.println("can't set property correctly : obj = " + obj.toString() + " name = " + name + " value = " + value);
		return false;
	}
	
	/**
	 * 首先尝试调用对象的setter方法,因为setter方法中可能存在处理逻辑.
	 * 无法调用setter的情况下再尝试直接给属性赋值
	 */
	public static boolean setProperty(Object obj,String name,Object value) {
		Class<?> clazz = obj.getClass();
		Field field = null;
		Method setter = null;
		try {
			field = clazz.getDeclaredField(name);
		} catch (Exception e) {
			try {
				//再尝试找一级父类的私有属性,找太多层没有意义
				field = clazz.getSuperclass().getDeclaredField(name);
			} catch (Exception e1) {}
		}
		
		if(null != field) {
			Class<?> type = field.getType();
			
			try {
				//1.获取正常的setter,setName
				setter = clazz.getMethod("set" + name.substring(0, 1).toUpperCase() + name.substring(1),type);
			} catch (NoSuchMethodException e) {
				try {
					//2.如变量aName的setter就是setaName();
					setter = clazz.getMethod("set" + name,type);
				} catch (NoSuchMethodException e1) {}
			}
		}
		
		
		try {
			if(null != setter) {
				Class<?>[] clasees = setter.getParameterTypes();
				if(clasees.length != 1) {
					System.err.println("can't find the method which has one parameter");
					return false;
				}
				if(null == value) {
					setter.invoke(obj,new Object[]{null});
					return true;
				}else {
					setter.invoke(obj,cast(clasees[0], value));
					return true;
				}
			}else if(null != field) {
				field.setAccessible(true);
				if(null == value) {
					field.set(obj,new Object[]{null});
					return true;
				}else {
					field.set(obj, cast(field.getType(), value));
					return true;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.err.println("can't set property correctly : [obj = " + obj.toString() + "],[name = " + name + "],[value = " + value + "]");
		return false;
	}
	
	public static Class<?> getFirstGenericClass(Class clazz){
		Type type = clazz.getGenericSuperclass();
		if(type instanceof ParameterizedType){
            ParameterizedType pType = (ParameterizedType)type;
            Type actualType = pType.getActualTypeArguments()[0];
            if( actualType instanceof Class ){
              return (Class<?>) type;
            }
        }
		return null;
	}
	
	/**
	 * @description 填充同名属性
	 * TODO org.apache.commons.beanutils.BeanUtils.populate
	 */
	public static Object fill(Map source, Class cls) {
		Object rtn = null;
		try {
			rtn = cls.newInstance();
		} catch (InstantiationException e1) {
			e1.printStackTrace();
		} catch (IllegalAccessException e1) {
			e1.printStackTrace();
		}
		for (Object key : source.keySet()) {
			try {
				Field field = cls.getDeclaredField(key.toString());
				field.setAccessible(true);

				/* 这里需要类型转换扩展 */
				if (source.get(key).getClass() == String[].class && field.getType() == String[].class) {
					field.set(rtn, source.get(key));
				} else if (source.get(key).getClass() == String[].class && field.getType() == String.class) {
					String[] value = (String[]) source.get(key);
					String result = "";
					for (int i = 0; i < value.length; i++) {
						if (i != 0) {
							result += ",";
						}
						result += value[i];
					}
					field.set(rtn, result);
				}
			} catch (NoSuchFieldException e) {
				continue;
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return rtn;
	}

	public static String getStringValue(Object obj, String key) {

		String value = "";
		if ("".equalsIgnoreCase(key) || null == key) {
			return value;
		}

		if (obj instanceof Map) {
			Map map = (Map) obj;
			Object v = map.get(key);
			if (null == v) {
				value = "";
			} else {
				if (v.getClass() == String[].class) {
					String[] _value = (String[]) v;
					if (_value.length > 0) {
						String _v = Arrays.toString(_value);
						value = _v.substring(1,_v.lastIndexOf("]"));
					} else {
						value = "";
					}
				} else {
					value = v.toString();
				}
			}
		} else {
			// 采用循环的方式获取Field,防止指定的名称大小写不同
			Field[] fields = obj.getClass().getDeclaredFields();
			for (int j = 0; j < fields.length; j++) {
				if (key.equalsIgnoreCase(fields[j].getName())) {
					Method getter = null;
					try {
						getter = obj.getClass().getMethod("get" + fields[j].getName().substring(0, 1).toUpperCase()
								+ fields[j].getName().substring(1));
						value = null == getter.invoke(obj) ? "" : getter.invoke(obj).toString();
					} catch (NoSuchMethodException e) {
						try {
							// 如变量aName的getter就是getaName();
							getter = obj.getClass().getMethod("get" + fields[j].getName());
							value = null == getter.invoke(obj) ? null : getter.invoke(obj).toString();
						} catch (NoSuchMethodException e1) {
							try {
								fields[j].setAccessible(true);
								value = null == fields[j].get(obj) ? "" : fields[j].get(obj).toString();
							} catch (Exception e2) {
								e2.printStackTrace();
							}
						} catch (Exception e2) {
							e2.printStackTrace();
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}
		return value;
	}

	@SuppressWarnings("unchecked")
	public static Map objToMap(Object obj) {
		Map adapterMap = new LinkedHashMap();
		String value = "";
		Field[] fields = obj.getClass().getDeclaredFields();
		for (int j = 0; j < fields.length; j++) {
			Method getter = null;
			try {
				getter = obj.getClass().getMethod(
						"get" + fields[j].getName().substring(0, 1).toUpperCase() + fields[j].getName().substring(1));
				value = null == getter.invoke(obj) ? "" : getter.invoke(obj).toString();
			} catch (NoSuchMethodException e) {
				try {
					// 如变量aName的getter就是getaName();
					getter = obj.getClass().getMethod("get" + fields[j].getName());
					value = null == getter.invoke(obj) ? null : getter.invoke(obj).toString();
				} catch (NoSuchMethodException e1) {
					try {
						fields[j].setAccessible(true);
						value = null == fields[j].get(obj) ? "" : fields[j].get(obj).toString();
					} catch (Exception e2) {
						e2.printStackTrace();
					}
				} catch (Exception e2) {
					e2.printStackTrace();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			adapterMap.put(fields[j].getName(), value);
		}
		return adapterMap;
	}
	/**为对象声明的属性(包括私有)设置值,返回true表示成功,返回false一般情况下是指定路径中不存在此类或
	 * 不存在此属性或参数类型不正确 */
	public static boolean setProperty(String className, String name, Object value) {
		
		try {
			Object obj = Class.forName(className).newInstance();
			if(null != obj){
				setProperty(obj, name, value);
			}
			return true;
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	/**从给定对象中取出指定的属性,会先尝试从get方法中获取,如果没有,则直接从该属性中获取 */
	public static Object getProperty(Object obj, String name) {

		Object retValue = null;
		Field field = null;
		Class cls = obj.getClass();
		if (null != cls) {
			try {
				// 考虑到get方法中可能会有一些校验或默认值设置,所以先寻找get方法
				retValue = executeGetter(obj, name);
				// 没有get方法,则直接从属性中取
				if (null == retValue) {
					// 如果没有此属性,则在异常中从其父类再查找一次
					field = cls.getDeclaredField(name);
				}
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (NoSuchFieldException e) {
				Class clazz = obj.getClass().getSuperclass();
				try {
					if (null != clazz)
						field = cls.getDeclaredField(name);
				} catch (SecurityException e1) {
					e1.printStackTrace();
				} catch (NoSuchFieldException e1) {
					// 仍然没找到...添加处理
					e1.printStackTrace();
				}
				e.printStackTrace();
			}
		}
		if (null != field) {
			field.setAccessible(true);
			try {
				retValue = field.get(obj);
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}

		return retValue;
	}

	/**返回一个对象的访问修饰符(传入Field,Method的Class即可获得属性,方法的描述)的字符串描述 */
	public static String getModifyString(Class cls) {
		if(null!=cls){
			int modifier=cls.getModifiers();
			//Modifier类中包含的修饰符太多了,根据需要添加...
			switch (modifier){
			
				case Modifier.PUBLIC:
					return "public";
				case Modifier.PRIVATE:
					return "private";
				case Modifier.PROTECTED:
					return "protected";
				case Modifier.INTERFACE:
					return "interface";
				case Modifier.FINAL:
					return "final";
				case Modifier.STATIC:
					return "static";
			}
		}
		return null;
	}
	
	/**使用多参构造方法创建对象 */
	@SuppressWarnings("unchecked")
	public static Object newInstance(Class cls, Class[] paramTypes, Object[] params) {
		try {
			Constructor constructor=cls.getConstructor(paramTypes);
			constructor.setAccessible(true);
			return constructor.newInstance(params);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	/**使用多参构造方法创建对象 */
	public static Object newInstance(String clazz, Class<?> paramTypes, Object params) {
		Class<?> cls = null;
		try {
			cls = Class.forName(clazz);
			Constructor constructor = cls.getDeclaredConstructor(paramTypes);
			constructor.setAccessible(true);
			return constructor.newInstance(params);
		} catch (Exception e) {
			e.printStackTrace();
			try {
				Constructor constructor = cls.getSuperclass().getConstructor(paramTypes);
				constructor.setAccessible(true);
				return constructor.newInstance(params);
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}
		return null;
	}
	
	@SuppressWarnings("unchecked")
	public static <T> T newInstance(String clazz) {
		try {
			return (T) Class.forName(clazz).newInstance();
		} catch (Exception e) {
//			e.printStackTrace();
			return null;
		}
	}
	
	
	/**当Class对象被创建时,对象中会保存所有方法数组的引用publicMethods和declaredMethods,而
	 * 使用cls.getMethod(...)会到内存中重新查找,所以这里选择了前者,同样也会避免拼接get方法
	 * 时由于属性命名不规范(如aPple)而可能带来的异常 */
	public static Object executeGetter(Object obj, String name) {
		Object retValue=null;
		Class cls=obj.getClass();
		Method[] methods=cls.getMethods();
		for (int i = 0; i < methods.length; i++) {
			if(methods[i].getName().equalsIgnoreCase("get"+name)){
				//Log.log("get"+name);
				try {
					retValue=methods[i].invoke(obj);
					return retValue;
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}

	/**如果未定义Set方法,不会强制为此属性赋值 */
	public static boolean executeSetter(Object obj, String name, Object paramValue) {
		Class cls=obj.getClass();
		Method[] methods=cls.getMethods();
		for (int i = 0; i < methods.length; i++) {
			if(methods[i].getName().equalsIgnoreCase("set"+name)){
				try {
					methods[i].invoke(obj,paramValue);
					return true;
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}
		}
		return false;
	}

	/**考虑到方法重载问题 ,这里使用cls.getMethod(...)方法获取Method方法,
	 * 给定的参数顺序要与被调用方法定义的参数顺序相同
	 * 1.无参方法  */
	@SuppressWarnings("unchecked")
	public static <T> T executeMethod(Object obj, String methodName) {
		return (T) executeMethod(obj, methodName,null,null);
	}
	
	/**2.有参无重载方法 */
	@SuppressWarnings("unchecked")
	public static <T> T executeMethod(Object obj, String methodName, Object...paramValues) {
		return (T) executeMethod(obj, methodName,paramValues,null);
	}
	
	/**3.有参有重载方法 */
	@SuppressWarnings("unchecked")
	public static <T> T  executeMethod(Object obj, String methodName, Object[] paramValues, Class[] paramTypes) {
		//无参
		Class cls = obj.getClass();
		try {
			if (null == paramTypes && null == paramValues) {
				Method method = cls.getMethod(methodName);
				return (T) method.invoke(obj);
			} else if (null == paramTypes) {// 有参无重载方法,按默认排序查找方法
				Class[] defaultTypes = new Class[paramValues.length];
				for (int i = 0; i < paramValues.length; i++) {
					defaultTypes[i] = paramValues[i].getClass();
				}
				Method method = cls.getMethod(methodName, defaultTypes);
				return (T) method.invoke(obj, paramValues);
			} else {// 有参有重载,需要按照给定的参数类型顺序查找对应的重载方法
				if (paramTypes.length != paramValues.length) {
					return null;
				}
				Method method = cls.getMethod(methodName, paramTypes);
				return (T) method.invoke(obj, paramValues);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	/**判断对象是否有指定方法 */
	public static boolean hasMethod(Object obj, String methodName) {
		Class cls=obj.getClass();
		Method[] methods=cls.getMethods();
		for (int i = 0; i < methods.length; i++) {
			if(methods[i].getName().equalsIgnoreCase(methodName)){
				return true;
			}
		}
		return false;
	}
	private static SimpleDateFormat sdf_datetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private static SimpleDateFormat sdf_date = new SimpleDateFormat("yyyy-MM-dd");
	
	@SuppressWarnings({ "unchecked" })
	public static <T> T cast(Class<T> target,Object source,T defaultValue){
		
		if(null == source){
			return defaultValue;
		}
		Class clazz;
		Class<?> cls = source.getClass();
		if(target == String.class){
			if(cls == Date.class){
				String rtn = sdf_datetime.format((Date)source);
				if(rtn.contains("00:00:00")){
					rtn = sdf_date.format((Date)source);
				}
				return (T)rtn;
			}else{
				return (T) source.toString();
			}
		}else if(target == Double.class || target == double.class){
			clazz = Double.class;
			if(cls == String.class){
				return (T)clazz.cast(Double.parseDouble((String) source));
			}else if(cls == Double.class || cls == double.class){
				return (T)source;
			}else if(cls == Integer.class || cls == int.class){
				return (T)clazz.cast(((Integer)source).doubleValue());
			}else if(cls == Float.class || cls == float.class){
				return (T)clazz.cast(((Float)source).doubleValue());
			}else if(cls == Long.class || cls == long.class){
				return (T)clazz.cast(((Long)source).doubleValue());
			}else if(cls == Boolean.class || cls == boolean.class){
				if((boolean)source){
					return (T)clazz.cast(1d);
				}else{
					return (T)clazz.cast(0d);
				}
			}
		}else if(target == Integer.class || target == int.class){
			clazz = Integer.class;
			if(cls == String.class){
				//有小数点时肯定会强转失败，正确的做法应该是先取Double/Float等值后再取intValue();
				String _source = (String) source;
				if(_source.indexOf(".") > 0){
					_source = _source.substring(0,_source.indexOf("."));
				}
				return (T)clazz.cast(Integer.parseInt(_source));
			}else if(cls == Double.class || cls == double.class){
				return (T)clazz.cast(((Double)source).intValue());
			}else if(cls == Integer.class || cls == int.class){
				return (T)source;
			}else if(cls == Float.class || cls == float.class){
				return (T)clazz.cast(((Float)source).intValue());
			}else if(cls == Long.class || cls == long.class){
				return (T)clazz.cast(((Long)source).intValue());
			}else if(cls == Boolean.class || cls == boolean.class){
				if((boolean)source){
					return (T)clazz.cast(1);
				}else{
					return (T)clazz.cast(0);
				}
			}
		}else if(target == Float.class || target == float.class){
			clazz = Float.class;
			if(cls == String.class){
				return (T)clazz.cast(Float.parseFloat((String) source));
			}else if(cls == Double.class || cls == double.class){
				return (T)clazz.cast(((Double)source).floatValue());
			}else if(cls == Integer.class || cls == int.class){
				return (T)clazz.cast(((Integer)source).floatValue());
			}else if(cls == Float.class || cls == float.class){
				return (T)source;
			}else if(cls == Long.class || cls == long.class){
				return (T)clazz.cast(((Long)source).floatValue());
			}else if(cls == Boolean.class || cls == boolean.class){
				if((boolean)source){
					return (T)clazz.cast(1f);
				}else{
					return (T)clazz.cast(0f);
				}
			}
		}else if(target == Long.class || target == long.class){
			clazz = Long.class;
			if(cls == String.class){
				return (T)clazz.cast(Long.parseLong((String) source));
			}else if(cls == Double.class || cls == double.class){
				return (T)clazz.cast(((Double)source).longValue());
			}else if(cls == Integer.class || cls == int.class){
				return (T)clazz.cast(((Integer)source).longValue());
			}else if(cls == Float.class || cls == float.class){
				return (T)clazz.cast(((Float)source).longValue());
			}else if(cls == Long.class || cls == long.class){
				return (T)source;
			}else if(cls == Boolean.class || cls == boolean.class){
				if((boolean)source){
					return (T)clazz.cast(1l);
				}else{
					return (T)clazz.cast(0l);
				}
			}
		}else if(target == Boolean.class || target == boolean.class){
			clazz = Boolean.class;
			if(cls == String.class){
				return (T) clazz.cast(Boolean.parseBoolean((String) source));
			}else if(cls == Double.class || cls == double.class){
				int v = ((Double)source).intValue();
				boolean b = false;
				if(v == 1){
					b = true;
				}
				return (T) clazz.cast(b);
			}else if(cls == Integer.class || cls == int.class){
				int v = (int) source;
				boolean b = false;
				if(v == 1){
					b = true;
				}
				return (T) clazz.cast(b);
			}else if(cls == Float.class || cls == float.class){
				int v = ((Float)source).intValue();
				boolean b = false;
				if(v == 1){
					b = true;
				}
				return (T) clazz.cast(b);
			}else if(cls == Long.class || cls == long.class){
				int v = ((Long)source).intValue();
				boolean b = false;
				if(v == 1){
					b = true;
				}
				return (T) clazz.cast(b);
			}else if(cls == Boolean.class || cls == boolean.class){
				return (T) source;
			}
		}else if(target == Date.class){
			if(cls == String.class){
				try {
					return target.cast(sdf_datetime.parse((String) source));
				} catch (Exception e) {
					try {
						return target.cast(sdf_date.parse((String) source));
					} catch (ParseException e1) {
						try {
							return (T) new Date(Long.parseLong((String) source));
						} catch (Exception e2) {
							return null;
						}
					}
				}
			}else if(cls == Double.class || cls == double.class){
				return (T) new Date(((Double)source).longValue());
			}else if(cls == Integer.class || cls == int.class){
				return (T) new Date(((Integer)source).longValue());
			}else if(cls == Float.class || cls == float.class){
				return (T) new Date(((Float)source).longValue());
			}else if(cls == Long.class || cls == long.class){
				return (T) new Date(((Long)source).longValue());
			}
		}else if(target == Class.class){
			try {
				return (T) source;
			} catch (Exception e) {
				e.printStackTrace();
				return null;
			}
		}else if(target == BigDecimal.class){
			if(cls == String.class){
				try {
					return (T) BigDecimal.valueOf(Double.parseDouble((String) source));
				} catch (Exception e) {
					e.printStackTrace();
					return null;
				}
			}
		}
		return target.cast(source);
	
	}
	public static <T> T cast(Class<T> target,Object source){
		return cast(target,source,null);
	}
	
	@SuppressWarnings("unchecked")
	public static <T extends Serializable> T deepClone(T obj) {

		T clonedObj = null;
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(baos);
			oos.writeObject(obj);
			oos.close();

			ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
			ObjectInputStream ois = new ObjectInputStream(bais);
			clonedObj = (T) ois.readObject();
			ois.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return clonedObj;
	}
	
	//获取泛型
	public static Class<?> getGenericEntityClass(String ress){
		try {
			Class<?> clazz = Class.forName(ress);
			//返回表示此 Class 所表示的实体（类、接口、基本类型或 void）的直接超类的 Type。  
			Type type = null;
	        Type[] genTypes = clazz.getGenericInterfaces();
	        for (int i = 0; i < genTypes.length; i++) {
	        	//TODO Object应该改为具体父类,比如BaseEntity这种
				if(genTypes[i].getTypeName().startsWith(Object.class.getName())){
					type = genTypes[i];
					break;
				}
			}
	        Class<?> cls = null;
	        if (!(type instanceof ParameterizedType)) {  
	        	cls = clazz;
	        }else{
	        	cls = (Class<?>) ((ParameterizedType)type).getActualTypeArguments()[0];
	        }
	        return cls;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public static <T> T fillGenericEntityTime(T t,boolean isCreate,boolean isUpdate){
		Class<?> cls = t.getClass();
		try {
			if(isCreate){
				if(null != cls.getDeclaredField("createTime")){
					Field field = cls.getDeclaredField("createTime");
					field.setAccessible(true);
					if(null == field.get(t)){
						field.set(t, cast(field.getType(), new Date()));
					}
				}
			}
		} catch (Exception e) {}
		
		
//		try {
//			if(isCreate){
//				if(null != cls.getDeclaredField("id")){
//					Field field = cls.getDeclaredField("id");
//					field.setAccessible(true);
//					if(null == field.get(t)){
//						field.set(t, cast(field.getType(), Str.randomNumId()));
//					}
//				}
//			}
//		} catch (Exception e) {}
		
		try {
			if(isUpdate){
				if(null != cls.getDeclaredField("updateTime")){
					Field field = cls.getDeclaredField("updateTime");
					field.setAccessible(true);
					field.set(t, cast(field.getType(), new Date()));
				}
			}
		} catch (Exception e) {}
		
		return t;
	}
	
}
